"use client";

import authClient from "@/auth/authClient";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Github, Package, Monitor, Wifi, WifiOff, AlertCircle, MessageSquare, Plus, Settings, Terminal as TerminalIcon } from "lucide-react";
import { useState, useEffect, useRef } from "react";
import { useParams } from "next/navigation";
import TerminalComponent from "@/components/Terminal";
import TerminalConfig from "@/components/TerminalConfig";
import { initApi, type API, type ChannelInfo, type TerminalOutput, type TerminalStatus, type TerminalInfo, type PeerInfo } from "@/lib/api";

interface TerminalState {
    id: number;
    sessionId: string;
    position: { x: number; y: number };
    size: { rows: number; cols: number };
    status: 'active' | 'inactive' | 'closed';
    nickname?: string;
    alias?: string;
    fontFamily?: string;
    fontSize?: number;
}

interface ChatMessage {
    id: string;
    sender: string;
    nickname?: string;
    content: string;
    sentAt: Date;
}

export default function TerminalPage() {
    const params = useParams();
    const id = params.id as string;
    const { data: session } = authClient.useSession();

    // Connection state
    const [api, setApi] = useState<API | null>(null);
    const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
    const [connected, setConnected] = useState(false);
    const [connectionStatus, setConnectionStatus] = useState<'connecting' | 'connected' | 'disconnected' | 'error'>('connecting');
    const [userId, setUserId] = useState<string>('');
    const [users, setUsers] = useState<[string, PeerInfo][]>([]);
    const [error, setError] = useState<string | null>(null);

    // Sync state
    const [syncStatus, setSyncStatus] = useState<'idle' | 'requesting' | 'syncing' | 'completed' | 'error'>('idle');
    const [syncMessage, setSyncMessage] = useState<string>('');
    const [lastSyncTime, setLastSyncTime] = useState<Date | null>(null);

    // Terminal state
    const [terminals, setTerminals] = useState<TerminalState[]>([]);
    const [activeTerminalId, setActiveTerminalId] = useState<number | null>(null);

    // Chat state
    const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);
    const [showChat, setShowChat] = useState(false);
    const [newMessages, setNewMessages] = useState(false);

    const subscriptionsRef = useRef<Set<() => void>>(new Set());
    const terminalRefs = useRef<Map<string, any>>(new Map());

    // Initialize connection immediately
    useEffect(() => {

        const initializeConnection = async () => {
            try {
                setConnectionStatus('connecting');
                setError(null);

                console.log('🚀 Initializing API...');
                const apiInstance = await initApi();
                setApi(apiInstance);

                console.log('📋 Joining channel with ticket:', id);
                const channel = await apiInstance.joinChannel(id, 'terminal-user');
                setCurrentSessionId(channel.id);

                // Set current user ID
                const myself = apiInstance.getMyself(channel.id);
                setUserId(myself.id);

                // Subscribe to messages for chat
                const unsubscribeMessages = apiInstance.subscribeToMessages(channel.id, (message) => {
                    console.info('New message received:', message);

                    // Add to chat
                    setChatMessages(prev => [...prev, {
                        id: message.id,
                        sender: message.sender,
                        nickname: message.nickname,
                        content: message.content,
                        sentAt: new Date()
                    }]);

                    if (!showChat) setNewMessages(true);
                });

                // Subscribe to terminal output
                const unsubscribeTerminalOutput = apiInstance.subscribeToTerminalOutput(channel.id, (output: TerminalOutput) => {
                    console.info(`Terminal output: ${JSON.stringify(output)}`);
                    if (terminalRefs.current.has(output.sessionId)) {
                        // Convert array of numbers to Uint8Array then decode
                        const uint8Array = new Uint8Array(output.data);
                        const text = new TextDecoder().decode(uint8Array);
                        console.info(`Terminal output: ${text}`);
                        const terminalInstance = terminalRefs.current.get(output.sessionId);
                        if (terminalInstance && terminalInstance.processRemoteOutput) {
                            terminalInstance.processRemoteOutput(text);
                        }
                    }
                });

                // Subscribe to terminal status
                const unsubscribeTerminalStatus = apiInstance.subscribeToTerminalStatus(channel.id, (status: TerminalStatus) => {
                    console.info('Terminal status:', status);
                    if (status.status === 'closed') {
                        // Remove terminal and cleanup reference
                        setTerminals(prev => prev.filter(t => t.sessionId !== status.sessionId));
                        terminalRefs.current.delete(status.sessionId);
                    }
                });

                // Subscribe to neighbors for connection status updates
                const unsubscribeNeighbors = apiInstance.subscribeToNeighbors(channel.id, (neighborCount: number) => {
                    console.log('🔗 Neighbor count updated:', neighborCount);

                    const hasRemotePeers = neighborCount > 0;
                    setConnected(hasRemotePeers);
                    setConnectionStatus(hasRemotePeers ? 'connected' : 'disconnected');

                    // Update peers list when neighbors change
                    const peers = apiInstance.getPeers(channel.id);
                    const updatedUsers: [string, PeerInfo][] = peers.map(peer => [peer.id, peer]);
                    setUsers(updatedUsers);

                    console.log('📡 Current peers:', peers.map(p => ({ id: p.id, name: p.name, role: p.role })));
                    setConnectionStatus('connected');
                    setConnected(true);

                                    });

                // Also subscribe to peers for additional updates
                const unsubscribePeers = apiInstance.subscribeToPeers(channel.id, () => {
                    const peers = apiInstance.getPeers(channel.id);

                    // Update users list
                    const updatedUsers: [string, PeerInfo][] = peers.map(peer => [peer.id, peer]);
                    setUsers(updatedUsers);
                });

                // Subscribe to terminal state synchronization events from the shared library
                const unsubscribeTerminalState = apiInstance.subscribeToTerminalState(channel.id, (stateMessage: any) => {
                    console.info('Terminal state sync received:', stateMessage);

                    // This handles TerminalState events from the shared library
                    if (stateMessage.terminals && Array.isArray(stateMessage.terminals)) {
                        const activeTerminals = stateMessage.terminals.filter((term: any) =>
                            term && term.session_id && term.status !== 'closed'
                        );

                        if (activeTerminals.length === 0) {
                            console.log('📋 No active terminals in state sync');
                            setSyncStatus('completed');
                            setSyncMessage('状态同步完成：无活跃终端');
                            setLastSyncTime(new Date());
                            return;
                        }

                        setSyncStatus('syncing');
                        setSyncMessage(`状态同步：正在处理 ${activeTerminals.length} 个终端...`);

                        // Process terminal state update
                        setTerminals(prev => {
                            const existingIds = new Set(prev.map(t => t.sessionId));
                            const newTerminals = activeTerminals
                                .filter((term: any) => {
                                    if (!term.session_id) {
                                        console.warn('⚠️ Terminal missing sessionId:', term);
                                        return false;
                                    }
                                    if (existingIds.has(term.session_id)) {
                                        console.log('ℹ️ Terminal already exists, skipping:', term.session_id);
                                        return false;
                                    }
                                    return true;
                                })
                                .map((term: any) => {
                                    const terminalId = parseInt(term.session_id) || Math.floor(Math.random() * 4294967295);
                                    console.log('✅ Adding terminal from state sync:', term.session_id, '→ ID:', terminalId);
                                    return {
                                        id: terminalId,
                                        sessionId: term.session_id,
                                        position: term.position || { x: 0, y: 0 },
                                        size: term.size || { rows: 24, cols: 80 },
                                        status: (term.status as 'active' | 'inactive' | 'closed') || 'active',
                                        alias: term.name || undefined
                                    };
                                });

                            if (newTerminals.length > 0) {
                                console.log('📋 Added terminals from state sync:', newTerminals.map((t: any) => `${t.sessionId}→${t.id}`));
                                const updatedTerminals = [...prev, ...newTerminals];

                                // Auto-select the first terminal if none is selected
                                if (!activeTerminalId && newTerminals.length > 0) {
                                    setActiveTerminalId(newTerminals[0].id);
                                }

                                setSyncStatus('completed');
                                setSyncMessage(`状态同步完成：添加了 ${newTerminals.length} 个终端`);
                                setLastSyncTime(new Date());

                                return updatedTerminals;
                            }

                            setSyncStatus('completed');
                            setSyncMessage('状态同步完成：无新终端');
                            setLastSyncTime(new Date());
                            return prev;
                        });
                    }
                });

                // Store subscriptions for cleanup
                subscriptionsRef.current.add(unsubscribeMessages);
                subscriptionsRef.current.add(unsubscribeTerminalOutput);
                subscriptionsRef.current.add(unsubscribeTerminalStatus);
                subscriptionsRef.current.add(unsubscribeNeighbors);
                subscriptionsRef.current.add(unsubscribePeers);
                subscriptionsRef.current.add(unsubscribeTerminalState);

                // Check initial connection status
                const initialPeers = apiInstance.getPeers(channel.id);
                const initialRemotePeers = initialPeers.filter(peer => peer.role !== 0);
                if (initialRemotePeers.length > 0) {
                    console.log('🔗 Already connected to remote peers, requesting sync...');
                    setConnected(true);
                    setConnectionStatus('connected');
                    requestTerminalSync(apiInstance, channel.id, myself.id);
                }

            } catch (err) {
                console.error('❌ Failed to initialize connection:', err);
                setError(err instanceof Error ? err.message : 'Failed to connect');
                setConnectionStatus('error');
            }
        };

        initializeConnection();

        return () => {
            // Cleanup subscriptions
            subscriptionsRef.current.forEach(unsubscribe => unsubscribe());
            subscriptionsRef.current.clear();

            if (currentSessionId && api) {
                api.closeChannel(currentSessionId);
            }
        };
    }, [id]);


    const requestTerminalSync = async (apiInstance: API, channelId: string, requesterId: string, isRetry = false) => {
        if (!apiInstance || !channelId) {
            console.warn('Cannot request sync: API or channel not available');
            return;
        }

        try {
            setSyncStatus('requesting');
            setSyncMessage(isRetry ? '正在等待远程终端状态同步...' : '正在等待远程终端状态同步...');
            console.log('🔄 Waiting for terminal state sync...', isRetry ? '(retry)' : '');

            // CLI automatically sends state sync when new nodes connect, so we just wait
            // Set timeout for state sync response
            setTimeout(() => {
                if (syncStatus === 'requesting' || syncStatus === 'syncing') {
                    console.warn('⚠️ State sync timeout, but this is normal if no terminals exist');
                    setSyncStatus('completed');
                    setSyncMessage('等待超时，可能无远程终端');
                    setLastSyncTime(new Date());
                }
            }, 5000); // 5 second timeout for state sync

        } catch (err) {
            console.error('Failed to wait for terminal sync:', err);
            setSyncStatus('error');
            setSyncMessage(isRetry ? '等待同步失败' : '等待同步失败');
        }
    };

    // Manual retry function
    const retrySync = () => {
        if (api && currentSessionId && userId) {
            requestTerminalSync(api, currentSessionId, userId, true);
        }
    };

    const createTerminal = async () => {
        if (!api || !currentSessionId || terminals.length >= 14) {
            alert('Maximum terminals reached or not connected');
            return;
        }

        try {
            const terminalId = Math.floor(Math.random() * 4294967295);
            const sessionId = terminalId.toString();

            // Check if terminal with this ID already exists
            if (terminals.some(t => t.sessionId === sessionId)) {
                console.warn('Terminal with this ID already exists:', sessionId);
                return;
            }

            await api.createTerminal(currentSessionId, sessionId);

            const newTerminal: TerminalState = {
                id: terminalId,
                sessionId,
                position: { x: 50, y: 50 },
                size: { rows: 24, cols: 80 },
                status: 'active'
            };

            setTerminals(prev => [...prev, newTerminal]);
            setActiveTerminalId(terminalId);

        } catch (err) {
            console.error('Failed to create terminal:', err);
            alert('Failed to create terminal');
        }
    };


    const closeTerminal = async (terminalId: number) => {
        console.log('closing terminal', terminalId);
        if (!api || !currentSessionId) return;

        try {
            await api.closeTerminal(currentSessionId, terminalId.toString());
            // Cleanup terminal reference
            terminalRefs.current.delete(terminalId.toString());
            setTerminals(prev => prev.filter(t => t.id !== terminalId));
            if (activeTerminalId === terminalId) {
                setActiveTerminalId(terminals.length > 1 ? terminals[0].id : null);
            }
        } catch (err) {
            console.error('Failed to close terminal:', err);
        }
    };

    // Terminal interface is always accessible, no login required

    return (
        <div className="h-screen flex flex-col bg-gray-900">
            {/* Top Action Bar */}
            <div className="bg-gray-800 border-b border-gray-700 px-4 py-2">
                <div className="flex items-center justify-between">
                    <div className="flex items-center space-x-4">
                        <div className="flex items-center space-x-2">
                            <TerminalIcon className="h-5 w-5 text-blue-400" />
                            <h1 className="text-lg font-semibold text-white">Terminal</h1>
                        </div>

                        {/* Terminal Selector */}
                        <div className="flex items-center space-x-2">
                            <span className="text-sm text-gray-400">Terminal:</span>
                            <Select
                                value={activeTerminalId?.toString() || ""}
                                onValueChange={(value) => setActiveTerminalId(parseInt(value))}
                            >
                                <SelectTrigger className="w-40 h-8 text-xs bg-gray-700 border-gray-600 text-white">
                                    <SelectValue placeholder="Select terminal" />
                                </SelectTrigger>
                                <SelectContent>
                                    {terminals.map((terminal) => (
                                        <SelectItem key={terminal.id} value={terminal.id.toString()}>
                                            {terminal.alias || `Terminal ${terminal.id}`}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>

                        {/* Connection Status */}
                        <div className="flex items-center space-x-2">
                            {connectionStatus === 'connected' && (
                                <div className="flex items-center text-green-400">
                                    <Wifi className="h-3 w-3 mr-1" />
                                    <span className="text-xs">Connected</span>
                                </div>
                            )}
                            {connectionStatus === 'connecting' && (
                                <div className="flex items-center text-yellow-400">
                                    <div className="h-3 w-3 mr-1 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent" />
                                    <span className="text-xs">Connecting...</span>
                                </div>
                            )}
                            {connectionStatus === 'disconnected' && (
                                <div className="flex items-center text-red-400">
                                    <WifiOff className="h-3 w-3 mr-1" />
                                    <span className="text-xs">Disconnected</span>
                                </div>
                            )}
                            {connectionStatus === 'error' && (
                                <div className="flex items-center text-red-400">
                                    <AlertCircle className="h-3 w-3 mr-1" />
                                    <span className="text-xs">Error</span>
                                </div>
                            )}
                        </div>

                        {/* Sync Status */}
                        <div className="flex items-center space-x-2">
                            {syncStatus === 'requesting' && (
                                <div className="flex items-center text-blue-400">
                                    <div className="h-3 w-3 mr-1 animate-spin rounded-full border-2 border-blue-400 border-t-transparent" />
                                    <span className="text-xs">Syncing...</span>
                                </div>
                            )}
                            {syncStatus === 'syncing' && (
                                <div className="flex items-center text-purple-400">
                                    <div className="h-3 w-3 mr-1 animate-pulse rounded-full bg-purple-400" />
                                    <span className="text-xs">Processing...</span>
                                </div>
                            )}
                            {syncStatus === 'completed' && lastSyncTime && (
                                <div className="flex items-center text-green-400">
                                    <div className="h-3 w-3 mr-1 rounded-full bg-green-400" />
                                    <span className="text-xs" title={`Last sync: ${lastSyncTime.toLocaleTimeString()}`}>
                                        Synced
                                    </span>
                                </div>
                            )}
                            {syncStatus === 'error' && (
                                <div className="flex items-center space-x-1 text-red-400">
                                    <AlertCircle className="h-3 w-3" />
                                    <span className="text-xs cursor-pointer hover:text-red-300" onClick={retrySync} title="Click to retry">
                                        Sync Error
                                    </span>
                                </div>
                            )}
                        </div>
                    </div>

                    <div className="flex items-center space-x-2">
                        {/* User Info */}
                        {/* <span className="text-xs text-gray-400"> */}
                        {/*     {session?.user?.email || "Anonymous User"} */}
                        {/* </span> */}
                        <span className="text-xs text-gray-400">•</span>
                        <span className="text-xs text-gray-400">{users.length} users</span>

                        {/* Quick Actions */}
                        <Button
                            variant="outline"
                            size="sm"
                            onClick={createTerminal}
                            disabled={!connected}
                            className="h-8 px-3 text-xs"
                        >
                            <Plus className="h-3 w-3 mr-1" />
                            New Terminal
                        </Button>

                        <Button
                            variant={showChat ? "default" : "outline"}
                            size="sm"
                            onClick={() => {
                                setShowChat(!showChat);
                                setNewMessages(false);
                            }}
                            className="relative h-8 px-3 text-xs"
                        >
                            <MessageSquare className="h-3 w-3 mr-1" />
                            {showChat ? "Hide Chat" : "Show Chat"}
                            {newMessages && (
                                <span className="absolute -top-1 -right-1 h-2 w-2 bg-red-500 rounded-full" />
                            )}
                        </Button>

                        {/* Config Button */}
                        {activeTerminalId && (
                            <TerminalConfig
                                channelId={currentSessionId}
                                terminalId={activeTerminalId.toString()}
                                currentNickname={terminals.find(t => t.id === activeTerminalId)?.nickname}
                                currentAlias={terminals.find(t => t.id === activeTerminalId)?.alias}
                                api={api}
                                onConfigUpdate={(config) => {
                                    setTerminals(prev => prev.map(term =>
                                        term.id === activeTerminalId ? { ...term, ...config } : term
                                    ));
                                }}
                            />
                        )}
                    </div>
                </div>
            </div>

            {/* Main content */}
            <main className="flex-1 relative overflow-hidden">
                {error && (
                    <div className="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
                        <Card className="w-96">
                            <CardHeader>
                                <CardTitle className="text-red-600 flex items-center">
                                    <AlertCircle className="h-5 w-5 mr-2" />
                                    Connection Error
                                </CardTitle>
                            </CardHeader>
                            <CardContent>
                                <p className="text-sm text-gray-600">{error}</p>
                            </CardContent>
                            <CardFooter>
                                <Button onClick={() => window.location.reload()} className="w-full">
                                    Retry
                                </Button>
                            </CardFooter>
                        </Card>
                    </div>
                )}

                {/* Terminal grid */}
                <div className="h-full p-4">
                    {terminals.length === 0 ? (
                        <div className="h-full flex items-center justify-center">
                            <div className="text-center">
                                <div className="text-gray-400 mb-4">No terminals created</div>
                                <Button onClick={createTerminal} disabled={!connected}>
                                    Create First Terminal
                                </Button>
                            </div>
                        </div>
                    ) : (
                        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 h-full">
                            {terminals.map((terminal) => (
                                <div key={terminal.id} className="bg-gray-800 rounded-lg border border-gray-700 flex flex-col">
                                    <div className="flex items-center justify-between p-2 border-b border-gray-700">
                                        <span className="text-sm text-gray-300">Terminal {terminal.id}</span>
                                        <div className="flex items-center space-x-2">
                                            <Button
                                                variant="ghost"
                                                size="sm"
                                                onClick={() => setActiveTerminalId(terminal.id)}
                                                className={`h-6 w-6 p-0 ${activeTerminalId === terminal.id ? 'bg-blue-600' : 'hover:bg-gray-700'
                                                    }`}
                                            >
                                                <div className="h-2 w-2 rounded-full bg-green-400" />
                                            </Button>
                                            <Button
                                                variant="ghost"
                                                size="sm"
                                                onClick={() => closeTerminal(terminal.id)}
                                                className="h-6 w-6 p-0 hover:bg-red-600"
                                            >
                                                ×
                                            </Button>
                                        </div>
                                    </div>
                                    <div className="flex-1">
                                        <TerminalComponent
                                            id={terminal.sessionId}
                                            api={api}
                                            sessionId={currentSessionId}
                                            fontFamily={terminal.fontFamily}
                                            fontSize={terminal.fontSize}
                                            onChatMessage={(message) => {
                                                if (api && currentSessionId) {
                                                    api.sendMessage(currentSessionId, message);
                                                }
                                            }}
                                            chatMessages={chatMessages}
                                            showChat={showChat}
                                            onTerminalReady={(terminalInstance) => {
                                                // Store terminal reference for output handling
                                                terminalRefs.current.set(terminal.sessionId, terminalInstance);
                                                console.log(`Terminal ${terminal.id} ready`);
                                            }}
                                        />
                                    </div>
                                </div>
                            ))}
                        </div>
                    )}
                </div>
            </main>

            {/* Footer */}
            <footer className="bg-gray-800 border-t border-gray-700 px-4 py-2">
                <div className="flex items-center justify-between text-sm text-gray-400">
                    <div>Powered by better-auth-cloudflare</div>
                    <div className="flex items-center gap-4">
                        <a
                            href="https://github.com/zpg6/better-auth-cloudflare"
                            target="_blank"
                            rel="noopener noreferrer"
                            className="flex items-center gap-1 hover:text-gray-200 transition-colors"
                        >
                            <Github size={14} />
                            <span>GitHub</span>
                        </a>
                        <a
                            href="https://www.npmjs.com/package/better-auth-cloudflare"
                            target="_blank"
                            rel="noopener noreferrer"
                            className="flex items-center gap-1 hover:text-gray-200 transition-colors"
                        >
                            <Package size={14} />
                            <span>npm</span>
                        </a>
                    </div>
                </div>
            </footer>
        </div>
    );
}
